﻿using MongoDB.Driver;
using Sustainalytics.ClientDW.Entities;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

namespace Sustainalytics.Reporting.BusinessLogic
{
    public class MongoDbContext : IMongoDbContext
    {
        public const string ConnectionStringName = "WiredTiger";
        public const string DatabaseName = "ClientDW_A";

        private static readonly IMongoClient _client;
        private static readonly IMongoDatabase _database;

        static MongoDbContext()
        {
            if (_database != null) return;

            var connectionString = ConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString;

            //_client = new MongoClient(connectionString);
            _client = new MongoClient(new MongoClientSettings
            {
                MaxConnectionPoolSize = 1000,
                Server = new MongoServerAddress("localhost", 27017)
            });

            _database = _client.GetDatabase(DatabaseName);
        }

        private MongoDbContext() { }

        public static IMongoDbContext GetInstance(string[] connectionStrings)
        {

            return new MongoDbContext();
        }



        public IMongoClient Client
        {
            get { return _client; }
        }

        public IMongoCollection<CorporateData> CorporateData
        {
            get { return _database.GetCollection<CorporateData>(typeof(CorporateData).Name); }
        }

        public IMongoCollection<IndicatorTemplate> IndicatorTemplates
        {
            get { return _database.GetCollection<IndicatorTemplate>(typeof(IndicatorTemplate).Name); }
        }

        public IMongoCollection<EventIndicator> EventIndicators
        {
            get { return _database.GetCollection<EventIndicator>(typeof(EventIndicator).Name); }
        }

        public IMongoCollection<Incident> Incidents
        {
            get { return _database.GetCollection<Incident>(typeof(Incident).Name); }
        }


        public async Task<List<T>> List<T>(Expression<Func<T, bool>> filter, CancellationToken cancellationToken)
        {
            var collection = _database.GetCollection<T>(typeof(T).Name);

            var list = await collection.Find(filter).ToListAsync(cancellationToken);

            return list;
        }

        public async Task<Dictionary<TKey, TSource>> Dictionary<TKey, TSource>(Expression<Func<TSource, bool>> filter, Func<TSource, TKey> keySelector, CancellationToken cancellationToken)
        {
            var collection = _database.GetCollection<TSource>(typeof(TSource).Name);

            var source = await collection.Find(filter).ToListAsync(cancellationToken);

            return source.ToDictionary(keySelector);
        }
    }
}
